/*
	LikeOS Keyboard Driver
	Copyright (C)2005 Nikolaos Rangos
*/
#include "windef.h"
#include "Hal.h"

// set1 scancodes .. we use set2 (default)
#define	KEY_LEFT_CTRL		0x1D
#define	KEY_LEFT_SHIFT		0x2A
#define	KEY_CAPS_LOCK		0x3A
#define	KEY_LEFT_ALT		0x38
#define	KEY_RIGHT_ALT		0x38	/* same as left */
#define	KEY_RIGHT_CTRL		0x1D	/* same as left */
#define	KEY_RIGHT_SHIFT		0x36
#define	KEY_SCROLL_LOCK		0x46
#define	KEY_NUM_LOCK		0x45
#define	KEY_DEL				0x53

/* German Keyboard Scancodes */
static const char german_kbd[] =
{
/* Unshifted */
	0x00,0x1b,'1' ,'2' ,'3' ,'4' ,'5' ,'6' ,
	'7' ,'8' ,'9' ,'0' ,0x9e,'\'',0x08,0x09,
	'q' ,'w' ,'e' ,'r' ,'t' ,'z' ,'u' ,'i' ,
	'o' ,'p' ,0x81,'+' ,0x0d,0x00,'a' ,'s' ,
	'd' ,'f' ,'g' ,'h' ,'j' ,'k' ,'l' ,0x94,
	0x84,'#' ,0x00,'~' ,'y' ,'x' ,'c' ,'v' ,
	'b' ,'n' ,'m' ,',' ,'.' ,'-' ,0x00,0x00,
	0x00,' ' ,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,'-' ,0x00,0x00,0x00,'+' ,0x00,
	0x00,0x00,0x00,0x7f,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	'<' ,0x00,0x00,'(' ,')' ,'/' ,'*' ,'7' ,
	'8' ,'9' ,'4' ,'5' ,'6' ,'1' ,'2' ,'3' ,
	'0' ,'.' ,0x0d,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/* Shifted */
	0x00,0x1b,'!' ,'"' ,0xdd,'$' ,'%' ,'&' ,
	'/' ,'(' ,')' ,'=' ,'?' ,'`' ,0x08,0x09,
	'Q' ,'W' ,'E' ,'R' ,'T' ,'Z' ,'U' ,'I' ,
	'O' ,'P' ,0x9a,'*' ,0x0d,0x00,'A' ,'S' ,
	'D' ,'F' ,'G' ,'H' ,'J' ,'K' ,'L' ,0x99,
	0x8e,'^' ,0x00,'|' ,'Y' ,'X' ,'C' ,'V' ,
	'B' ,'N' ,'M' ,';' ,':' ,'_' ,0x00,0x00,
	0x00,' ' ,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,'7' ,
	'8' ,0x00,'-' ,'4' ,0x00,'6' ,'+' ,0x00,
	'2' ,0x00,'0' ,0x7f,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	'>' ,0x00,0x00,'(' ,')' ,'/' ,'*' ,'7' ,
	'8' ,'9' ,'4' ,'5' ,'6' ,'1' ,'2' ,'3' ,
	'0' ,'.' ,0x0d,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/* Caps */
	0x00,0x1b,'1' ,'2' ,'3' ,'4' ,'5' ,'6' ,
	'7' ,'8' ,'9' ,'0' ,0x9e,'\'',0x08,0x09,
	'Q' ,'W' ,'E' ,'R' ,'T' ,'Z' ,'U' ,'I' ,
	'O' ,'P' ,0x9a,'+' ,0x0d,0x00,'A' ,'S' ,
	'D' ,'F' ,'G' ,'H' ,'J' ,'K' ,'L' ,0x99,
	0x8e,'#' ,0x00,'~' ,'Y' ,'X' ,'C' ,'V' ,
	'B' ,'N' ,'M' ,',' ,'.' ,'-' ,0x00,0x00,
	0x00,' ' ,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,'-' ,0x00,0x00,0x00,'+' ,0x00,
	0x00,0x00,0x00,0x7f,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	'<' ,0x00,0x00,'(' ,')' ,'/' ,'*' ,'7' ,
	'8' ,'9' ,'4' ,'5' ,'6' ,'1' ,'2' ,'3' ,
	'0' ,'.' ,0x0d,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/* Alternate */
	0x1a,'@' ,'\'','[' ,'(' ,']' ,0x00,
/* Alternate shifted */
	0x1a,'\\','\'','{' ,'(' ,'}' ,0x00,
/* Alternate Caps */
	0x1a,'@' ,'\'','[' ,'(' ,']' ,0x00
};

extern volatile char LikeOSIsBooting;
extern char textmode;

#if 0
void doKeyboardDispatch(char *s) {
	if (textmode == 1)
t_dispatch_keyboardevents(s);
	else
	w_dispatch_keyboardevents(s);
}
#endif

char keychar = '\0';

extern "C" char vga_getkey() {
	char keychar2 = keychar;
	keychar=0;
	return keychar2;
}
void interrupt_keyboard();
extern void SendEOI();
__declspec(naked) void kSVGAKeyboardHandler()
{

	_asm {
		PUSHAD
		PUSHFD
		CLI
	}

	_asm
	{
		call interrupt_keyboard
	}

	SendEOI();

	_asm
	{

		POPFD
		POPAD
		IRETD
	}
}

void interrupt_keyboard() {
	unsigned char scancode;
	unsigned status;
	unsigned mouse_data;
	unsigned char ascii;
	static unsigned make=0;
	char break_code=0;
	
	keychar = 0;
	
	for (;;) {
		status = InPortByte(0x64);
		if ((status & 0x01) == 0x01) break;
	}
	
	scancode = InPortByte(0x60);
	
	if ((scancode & 0x80)!=0x80) {	// no break codes please :) ok this will disable uppercase, but ... ok!
		if ((german_kbd[scancode] != 0x00) && (scancode != 0)) {
			// key pushed down			
			ascii=german_kbd[scancode];
			keychar=ascii;
			//if (LikeOSIsBooting != 1) doKeyboardDispatch(&s[0]);
		}
	}
}
